package bhbt.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import bhbt.tracer.Debug;







import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;


/**
 * 文件处理工具类
 * @author qiyh
 */
public class FileUtils {

    /**
     * 将Object对象输出,自动判断类型
     * @param response response
     * @param obj obj
     * @param fileName 文件名(支持中文)
     */
    public static void outWriteObject(HttpServletResponse response, Object obj, String fileName) throws Exception {
        response.reset();
        // 设置文件ContentType类型，自动判断下载文件类型
        response.setContentType("multipart/form-data");
        // 提示下载
        response.setHeader("Content-Disposition", "attachment;filename=" + StringUtil.strToISO(fileName));
        // 直接打开
        // response.setHeader("Content-Disposition", "inline;filename=" + StringUtil.strToISO(fileName));
        // 初始化输出流
        BufferedOutputStream os = new BufferedOutputStream(response.getOutputStream());
        InputStream is = null;
        try {
            if (null == obj) {
                return;
            } else if (obj instanceof byte[]) {
                byte[] buffer = (byte[]) obj;
                os.write(buffer, 0, buffer.length);
            } else if (obj instanceof HSSFWorkbook) {
                HSSFWorkbook wbook = (HSSFWorkbook) obj;
                wbook.write(os);
            } else if (obj instanceof InputStream) {
                is = (InputStream) obj;
                int maxFileSize = 3 * 1024 * 1024; // 3M
                byte[] buffer = new byte[maxFileSize];
                int length = 0;
                while ((length = is.read(buffer)) != -1) {
                    os.write(buffer, 0, length);
                }
            }
            response.flushBuffer();
        } catch (Exception e) {
            System.out.println("附件下载出现异常!");
            throw e;
        } finally {
            try {
                if (is != null)
                    is.close();
                if (os != null)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 得到文件后缀名(小写)
     * @param fileName fileName
     * @return String
     */
    public static String getFileExt(String fileName) {
        String ext = "";
        if (null != fileName && 1 < fileName.length()) {
            int i = fileName.lastIndexOf(".");
            if (i != -1)
                ext = fileName.substring(i + 1, fileName.length());
        }
        return ext.toLowerCase();
    }

    /**
     * @param filePath filePath
     * @return String
     */
    public static String getFilePathByOS(String filePath) {
        String os = System.getProperty("os.name");
        if (null == os) {
            os = "";
        }
        if (os.toLowerCase().indexOf("windows") < 0) {
        	// linux以opt开头
        	char c = filePath.charAt(1);
        	if(String.valueOf(c).equals(":")){
        		return "/opt/"+filePath.substring(3);
        	}
        }
        else {
        	char c = filePath.charAt(1);
        	if(!String.valueOf(c).equals(":")){
        		return "D:/"+filePath.substring(4);
        	}
        }
        return filePath;
    }

    /**
     * @author: qiyh
     * @Title: newFile
     * @Description: TODO 新建文件到磁盘
     * @param filePath 文件路径(包括文件名称和扩展名称)
     * @param inputStream 文件流
     * @return boolean true 创建成功、false 创建失败
     * @throws
     */
    public static boolean createFileToDisk(String filePath, InputStream inputStream) {
        try {
            if (null == filePath || "".equals(filePath)) {
                Debug.error("新建文件操作出错，错误原因：文件路径和文件名称为空！");
                return false;
            }
           
          //后缀名
			
		
			
            
            int bytesum = 0;
            int byteread = 0;
            // 如果存在先删除已存在的文件
            delFile(filePath);
            // 如果传入流为空直接结束操作
            if (null == inputStream) {
                Debug.error("新建" + filePath + "文件操作出错，错误原因：文件内容为null！");
                return false;
            }
            createDir(filePath);// 如果文件夹不存在 则建立新文件夹
            // 创建新的文件
            FileOutputStream fs = new FileOutputStream(filePath);
            byte[] buffer = new byte[1444];
            while ((byteread = inputStream.read(buffer)) != -1) {
                bytesum += byteread; // 字节数 文件大小
                fs.write(buffer, 0, byteread);
            }
            fs.flush();
            fs.close();
            inputStream.close();
            return true;
        } catch (Exception e) {
            Debug.error("新建" + filePath + "文件操作出错，错误原因：\r" + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @author: qiyh
     * @Title: delFile
     * @Description: TODO 删除文件
     * @param filePath 文件路径(包括文件名称和扩展名称)
     * @return boolean true 操作成功、false 操作失败
     * @throws
     */
    public static boolean delFile(String filePath) {
        try {
            // 文件名称为空 或为null时取消操作
            if (null == filePath || "".equals(filePath)) {
                Debug.error("删除" + filePath + "文件操作出错，错误原因：文件路径空！");
                return false;
            }
            File file = new File(filePath);
            if (file.exists()) {
                file.delete();
            }
            return true;
        } catch (Exception e) {
            Debug.error("删除" + filePath + "文件操作出错，错误原因：\r" + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Title: delFolder
     * @Description: TODO 删除文件夹
     * @param folderPath 文件夹路径(文件的存放的文件夹路径)
     * @return boolean true 操作成功、false 操作失败
     * @throws
     */
    public static boolean delFolder(String folderPath) {
        try {
            if (null == folderPath || "".equals(folderPath)) {
                Debug.error("新建目录操作出错，错误原因：目录为空！");
                return false;
            }
            if (!delAllFiles(folderPath)) {// 删除完里面所有内容
                Debug.error("删除文件夹下的所有文件操作出错。");
                return false;
            }
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); // 删除空文件夹
            return true;
        } catch (Exception e) {
            Debug.error("删除" + folderPath + "文件夹操作出错，错误原因：\r" + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Title: delAllFile
     * @Description: TODO 删除文件夹里面的所有文件
     * @param folderPath 文件夹路径(文件的存放的文件夹路径)
     * @return boolean true 操作成功、false 操作失败
     * @throws
     */
    public static boolean delAllFiles(String folderPath) {
        if (null == folderPath || "".equals(folderPath)) {
            Debug.error("删除文件夹里面的所有文件操作出错，错误原因：目录为空！");
            return false;
        }
        File file = new File(folderPath);
        if (!file.exists()) {
            return true;
        }
        if (!file.isDirectory()) {
            return true;
        }
        // 获取文件名称列表
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (folderPath.endsWith(File.separator)) {
                temp = new File(folderPath + tempList[i]);
            } else {
                temp = new File(folderPath + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                if (!delAllFiles(folderPath + "/ " + tempList[i])) {// 先删除文件夹里面的文件
                    return false;
                }
                if (!delFolder(folderPath + "/ " + tempList[i])) {// 再删除空文件夹
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * @Title: copyFile
     * @Description: TODO 复制单个文件
     * @param oldPath 复制的文件路径
     * @param newPath 复制后存放的路径
     * @return boolean true 操作成功、false 操作失败
     * @throws
     */
    public static boolean copyFile(String oldPath, String newPath ) {
    	InputStream is = null;
    	FileOutputStream os = null;
        try {
            if (null == oldPath || "".equals(oldPath)) {
                Debug.error("复制单个文件操作出错，错误原因：源文件为空！");
                return false;
            }
            if (null == newPath || "".equals(newPath)) {
                Debug.error("复制单个文件操作出错，错误原因：目标文件为空！");
                return false;
            }

            File oldfile = new File(oldPath);
            if (oldfile.exists()) { // 文件存在时
            	createDir(newPath);
                is = new FileInputStream(oldPath); // 读入原文件
                os = new FileOutputStream(newPath);
                byte[] buffer = new byte[1444];
                int byteread = 0;
                while ((byteread = is.read(buffer)) != -1) {
                    os.write(buffer, 0, byteread);
                }
            }
            return true;
        } catch (Exception e) {
            Debug.error("复制单个文件从" + oldPath + "到" + newPath + "操作出错，错误原因：\r" + e.getMessage());
            e.printStackTrace();
            return false;
        }finally{
        	try {
                if (is != null)
                    is.close();
                if (os != null)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @Title: copyFolder
     * @Description: TODO 复制整个文件夹内容
     * @param oldPath 需要复制的文件夹
     * @param newPath 复制后存放的文件夹
     * @return boolean true 操作成功、false 操作失败
     * @throws
     */
    public static boolean copyFolder(String oldPath, String newPath) {
        try {
            if (null == oldPath || "".equals(oldPath)) {
                Debug.error("复制整个文件夹内容操作出错，错误原因：目标文件为空！");
                return false;
            }
            if (null == newPath || "".equals(newPath)) {
                Debug.error("复制整个文件夹内容操作出错，错误原因：新文件为空！");
                return false;
            }
            createDir(newPath);// 如果文件夹不存在 则建立新文件夹
            File a = new File(oldPath);
            // 文件名称列表
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }
                if (temp.isFile()) {
                    FileInputStream input = new FileInputStream(temp);
                    FileOutputStream output = new FileOutputStream(newPath + "/ " + (temp.getName()).toString());
                    byte[] b = new byte[1024 * 5];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                if (temp.isDirectory()) {// 如果是子文件夹
                    copyFolder(oldPath + "/ " + file[i], newPath + "/ " + file[i]);
                }
            }
            return true;
        } catch (Exception e) {
            Debug.error("复制单个文件夹从" + oldPath + "到" + newPath + "操作出错，错误原因：\r" + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * @Title: moveFile
     * @Description: TODO 移动文件到指定目录
     * @param oldPath 需要移动的文件路径
     * @param newPath 移动的位置
     * @return boolean true 操作成功、false 操作失败
     * @throws
     */
    public static boolean moveFile(String oldPath, String newPath) {
        if (!copyFile(oldPath, newPath)) {
            return false;
        }
        if (delFile(oldPath)) {
            return false;
        }
        return true;
    }

    /**
     * @Title: moveFolder
     * @Description: TODO 移动文件夹到指定目录
     * @param oldPath 需要移动的文件夹
     * @param newPath 移动的位置
     * @return boolean true 操作成功、false 操作失败
     * @throws
     */
    public static boolean moveFolder(String oldPath, String newPath) {
        if (!copyFolder(oldPath, newPath)) {
            return false;
        }
        if (!delFolder(oldPath)) {
            return false;
        }
        return true;
    }
    
    public static boolean createDir(String path){
    	if(path!=null && 0<path.length()){
    		File file = new File(path);
    		if(file.isDirectory()){
    			return file.mkdirs();
    		}else{
    			return file.getParentFile().mkdirs();
    		}
    	}
    	return false;
    }
    
    public static List getFileList(String path, boolean shortName){
		List list = new ArrayList();
		if(StringUtils.isNotBlank(path)){
			File file = new File(path);
			if(file.exists()){
				String[] files = file.list();
				for (String filename : files) {
					int idx = filename.lastIndexOf("\\");
					if(shortName && 0<idx)
						filename = filename.substring(idx+1);
					list.add(filename);
				}
			}
		}
		return list;
	}
    
    /**
	 * new文件名= 时间 + 全球唯一编号
	 * @param fileName
	 * @return new文件名
	 */
	public static String getUUIDFileName(String fileName) {
		String uuid = UUID.randomUUID().toString();
		int position = fileName.lastIndexOf(".");
		String extension = fileName.substring(position);
		return uuid + extension;
	}



}
